#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include <sys/wait.h>
#include "Socket.hpp"

namespace TcpServerModule
{
    using namespace SocketModule;
    using tcphandler_t = std::function<bool(SockPtr, InetAddr)>;
    // TcpServer只负责进行IO,不对协议做任何的处理
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _listensockfd(std::make_unique<TcpSocket>()),
              _isrunning(false), _port(port)
        {
        }
        void InitTcpServer(tcphandler_t handler)
        {
            _handler = handler;
            _listensockfd->BuildTcpSocketMethod(_port);
        }
        void Loop() // 循环
        {
            _isrunning = true;
            while (_isrunning)
            {
                // 1.accept
                InetAddr client; // 保存客户端信息
                auto sockfd = _listensockfd->Accepter(&client);
                if (sockfd == nullptr)
                {
                    continue;
                }
                // 2.IO通信
                // 孙子进程
                int id = fork();
                if (id == 0) // 子进程
                {
                    _listensockfd->Close();
                    if (fork()) // 子进程直接退出,孙子进程执行任务
                    {
                        exit(0);
                    }
                    // 孙子进程
                    _handler(sockfd, client); // 执行回调方法
                    exit(0);
                }
                // 父进程
                sockfd->Close();
                waitpid(id, nullptr, 0);
            }
            _isrunning = false;
        }
        ~TcpServer()
        {
            _listensockfd->Close();
        }

    private:
        std::unique_ptr<Socket> _listensockfd; // 一定要有一个监听的
        bool _isrunning;
        int _port;
        tcphandler_t _handler;
    };
}